﻿using Domain.Entity;
using DtoFw;
using DtoFw.Query;
using Repository;
using System;
using System.Collections.Generic;
using System.Text;
using Util;
using System.Linq;
using Service.Base;
using DtoFw.Result;
using SqlSugar;
using DtoFw.Base;
using Cache;
using Repository.Base;

namespace Service
{
    public class EvidenceTransfereService : BaseService
    {
        private readonly CasePhysicalEvidenceRepository _casePhysicalEvidenceRepository;
        private readonly MainImgRepository _mainImgRepository;
        private readonly RoomBoxRepository _roomBoxRepository;
        private readonly MainUserRepository _mainUserRepository;
        private readonly CasePhysicalEvidenceTransfereRepository _casePhysicalEvidenceTransfereRepository;
        private readonly CasePhysicalApproveListRepository _approveListRepository;
        private readonly NotificationRepository _notificationRepository;
        private readonly CaseAttachFileRepository _attachFileRepository;

        public EvidenceTransfereService(CasePhysicalEvidenceRepository casePhysicalEvidenceRepository, MainImgRepository mainImgRepository,
               CasePhysicalEvidenceTransfereRepository casePhysicalEvidenceTransfereRepository, RoomBoxRepository roomBoxRepository,
            MainSerialNumberRepository mainSerialNumberRepository, MainUserRepository mainUserRepository, CasePhysicalApproveListRepository approveListRepository,
            NotificationRepository notificationRepository, CaseAttachFileRepository attachFileRepository) : base(mainSerialNumberRepository)
        {
            _casePhysicalEvidenceRepository = casePhysicalEvidenceRepository;
            _casePhysicalEvidenceTransfereRepository = casePhysicalEvidenceTransfereRepository;
            _roomBoxRepository = roomBoxRepository;
            _mainImgRepository = mainImgRepository;
            _mainUserRepository = mainUserRepository;
            _approveListRepository = approveListRepository;
            _notificationRepository = notificationRepository;
            _attachFileRepository = attachFileRepository;
        }
        /// <summary>
        /// 流转记录
        /// </summary>
        /// <param name="reqDto"></param>
        /// <returns></returns>
        public BaseGenericResult<Pager<EvidenceTransferePagerRespDto>> QueryEvidenceTransferePager(EvidenceTransfereQueryReqDto reqDto)
        {
            var pager = _casePhysicalEvidenceTransfereRepository.QueryEvidenceTransferePager(reqDto);
            return BaseGenericResult<Pager<EvidenceTransferePagerRespDto>>.Succeed(pager);
        }
        /// <summary>
        /// 获取流转物品
        /// </summary>
        /// <param name="TransfereId"></param>
        /// <returns></returns>
        public BaseGenericResult<List<TransfereEvidenceRespDto>> GetTransfereEvidences(long TransfereId)
        {
            return _casePhysicalEvidenceTransfereRepository.GetTransfereEvidences(TransfereId);
        }
        /// <summary>
        /// 新增
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<TransfereEvidencePostRespDto> Post(EvidenceTransfereListPostReqDto evidenceTransfereReqDto)
        {
            TransfereEvidencePostRespDto transfereEvidencePostRespDto = new TransfereEvidencePostRespDto();
            var deliveryNo = base.GetNumber(evidenceTransfereReqDto.OrganId, DtoFw.Enum.EnumSystemNumber.PZBH);
            var evidenceIds = evidenceTransfereReqDto.list.Select(x => x.EvidenceId)?.ToList();
            string dName = string.Empty;
            long? firstLocationId = 0;
            if (evidenceTransfereReqDto.Status != 1)
            {
                var _code = evidenceTransfereReqDto.list.FirstOrDefault().DeliveryDicType.ToString();
                var parentId = _roomBoxRepository.GetDb().Queryable<MainDicEntity>().Where(m => m.ParentId == 0 && m.Code == "CKYY").First()?.Id;
                dName = _roomBoxRepository.GetDb().Queryable<MainDicEntity>().Where(m => m.ParentId == parentId && m.Code == _code).First()?.Name;
            }

            var list = AutoMapperExtension.MapTo<EvidenceTransfereReqDto, CasePhysicalEvidenceTransfereEntity>(evidenceTransfereReqDto.list)?.Select(x =>
            {
                x.DeliveryNo = deliveryNo;
                x.DeliveryTime = DateTime.Now;
                x.Creator = evidenceTransfereReqDto.UserName;
                x.CreatorId = evidenceTransfereReqDto.UserId;
                x.DeliveryDicTypeName = evidenceTransfereReqDto.Status != 1 ? dName : x.DeliveryDicTypeName;
                if (!string.IsNullOrWhiteSpace(x.Receiver))
                {
                    x.Transferor = evidenceTransfereReqDto.UserName;
                    x.TransferorPhone = evidenceTransfereReqDto.Mobile;
                    x.TransferorOrgan = evidenceTransfereReqDto.OrganName;
                }
                else
                {
                    x.Receiver = evidenceTransfereReqDto.UserName;
                    x.ReceiverPhone = evidenceTransfereReqDto.Mobile;
                    x.ReceiverOrgan = evidenceTransfereReqDto.OrganName;
                }
                return x;
            })?.ToList();
            var first = evidenceTransfereReqDto.list.First();
            var total = evidenceTransfereReqDto.list.Sum(x => x.EvidenceQuantity);
            if (evidenceTransfereReqDto.Status == 1)
            {
                firstLocationId = first.LocationId;
                //1：入库
                var box = _roomBoxRepository.GetDb().Queryable<RoomBoxEntity>()
                   .Where(x => x.Id == first.LocationId && !x.IsDeleted)?.First();
                if ((box.Total - box.EviCount) < total)
                    return BaseGenericResult<TransfereEvidencePostRespDto>.Failure(transfereEvidencePostRespDto, $"{box.Name}箱子位置空间不足");
                box.EviCount += total;
                box.OrganId = evidenceTransfereReqDto.OrganId;
                box.Modifyer = evidenceTransfereReqDto.UserName;
                box.ModifyerId = evidenceTransfereReqDto.UserId;
                _roomBoxRepository.GetDb().Updateable<RoomBoxEntity>(box).ExecuteCommand();
            }
            else
            {
                //2：出库
                var locations = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceTransfereEntity>()
                         .Where(x => !x.IsDeleted && evidenceIds.Contains(x.EvidenceId) && x.HistoryStatus == 0)?
                      .Select(x => new
                      {
                          LocationId = x.LocationId,
                          quantity = x.EvidenceQuantity
                      })?.ToList();

                firstLocationId = locations.First().LocationId;
                var locs = (from t in locations
                            group t by new { t.LocationId }
                               into grp
                            select new
                            {
                                LocationId = grp.Key.LocationId,
                                Quantity = grp.Sum(t => t.quantity)
                            }).ToList();


                var locationIds = locs.Select(x => x.LocationId)?.ToList();
                var boxs = _roomBoxRepository.GetDb().Queryable<RoomBoxEntity>().Where(x => !x.IsDeleted && locationIds.Contains(x.Id))?.ToList()
                    .Select(x =>
                    {
                        x.EviCount -= locs.Find(y => y.LocationId == x.Id)?.Quantity;
                        x.OrganId = evidenceTransfereReqDto.OrganId;
                        x.Modifyer = evidenceTransfereReqDto.UserName;
                        x.ModifyerId = evidenceTransfereReqDto.UserId;
                        return x;
                    })?.ToList();

                _roomBoxRepository.GetDb().Updateable<RoomBoxEntity>(boxs).ExecuteCommand();
                foreach (var item in list)
                {
                    var model = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceTransfereEntity>()
                        .Where(x => !x.IsDeleted && x.EvidenceId == item.EvidenceId && x.HistoryStatus == 0 && x.EvidenceStatus == 1)?.First();
                    if (model == null)
                        continue;
                    item.Location = model.Location;
                    item.LocationId = model.LocationId;
                }
            }
            _casePhysicalEvidenceTransfereRepository.GetDb().Updateable<CasePhysicalEvidenceTransfereEntity>()
                .SetColumns(x => new CasePhysicalEvidenceTransfereEntity()
                {
                    HistoryStatus = 1,
                    OrganId = evidenceTransfereReqDto.OrganId,
                    Modifyer = evidenceTransfereReqDto.UserName,
                    ModifyerId = evidenceTransfereReqDto.UserId
                })
                .Where(x => evidenceIds.Contains(x.EvidenceId) && !x.IsDeleted).ExecuteCommand();
            var tuple = _casePhysicalEvidenceTransfereRepository.InsertBatchReturn(list);
            if (tuple.result > 0)
            {
                var evidences = _casePhysicalEvidenceRepository.Query(new BaseQuery(), x => x.Where(m => evidenceIds.Contains(m.Id)))?.ToList()
                    .Select(x =>
                    {
                        x.Status = evidenceTransfereReqDto.Status;
                        x.InQuantity = evidenceTransfereReqDto.Status == 1 ? x.Quantity : 0;
                        x.OutQuantity = evidenceTransfereReqDto.Status == 2 ? x.Quantity : 0;
                        x.Location = evidenceTransfereReqDto.list.FirstOrDefault(x => x.EvidenceId == x.EvidenceId)?.Location;
                        x.Modifyer = evidenceTransfereReqDto.UserName;
                        x.ModifyerId = evidenceTransfereReqDto.UserId;
                        x.OrganId = evidenceTransfereReqDto.OrganId;
                        return x;
                    })?.ToList();
                _casePhysicalEvidenceRepository.GetDb().Updateable(evidences).ExecuteCommand();
                if (evidenceTransfereReqDto.Status == 2)
                {
                    _approveListRepository.UseEvidenceApprove(evidenceIds, "出库", evidenceTransfereReqDto.UserName, evidenceTransfereReqDto.UserId);
                }
                else
                {
                    //修改通知已处理
                    //_casePhysicalEvidenceRepository.ModiftyNotificationHandler(evidenceIds.ToArray(), evidenceTransfereReqDto.UserName, "及时入库");
                }

                var imgs = new List<MainImgEntity>();

                foreach (var id in list.Select(v => v.EvidenceId))
                {
                    foreach (var item in evidenceTransfereReqDto.imgs)
                    {
                        var img = _mainImgRepository.Get(new BaseQuery(), t => t.Where(m => m.Url == item));
                        if (img != null)
                        {
                            img.RelevanceId = 0;
                            img.RelevanceNo = deliveryNo;
                            imgs.Add(img);
                        }
                    }
                }
                if (imgs.Count > 0)
                {
                    _mainImgRepository.GetDb().Updateable(imgs).ExecuteCommand();
                }
                transfereEvidencePostRespDto.DeliveryTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                transfereEvidencePostRespDto.DeliveryNo = deliveryNo;
                transfereEvidencePostRespDto.CabinetCode = _casePhysicalEvidenceTransfereRepository.GetCabinetCode(firstLocationId);
                transfereEvidencePostRespDto.SignImg = _mainUserRepository.GetDb().Queryable<MainUserEntity>()
                    .First(x => !x.IsDeleted && x.Id == evidenceTransfereReqDto.UserId)?.Extend1;

                //处理通知
                _notificationRepository.HandleWarnCasePhysicalEvidences(evidenceIds, "admin");

                return BaseGenericResult<TransfereEvidencePostRespDto>.Succeed(transfereEvidencePostRespDto);
            }



            return BaseGenericResult<TransfereEvidencePostRespDto>.Failure(transfereEvidencePostRespDto, "操作失败");
        }

        /// <summary>
        /// 附件上传 拍照
        /// </summary>
        /// <param name="user"></param>
        /// <param name="caseid"></param>
        /// <param name="evidenceId"></param>
        /// <param name="fileInfo"></param>
        /// <param name="byts"></param>
        /// <returns></returns>
        public bool UploadCaseAttachFile(long evidenceId, string url, string userName, long userId)
        {
            var entity = _casePhysicalEvidenceRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>().First(x => x.Id == evidenceId);

            var e = new CaseAttachFileEntity()
            {
                CaseId = entity == null ? 0 : entity.CaseId,
                EvidenceId = Convert.ToInt64(evidenceId),
                Title = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
                Path = url,
                Size = 3000,
                Ext = "jpg",
                CreateTime = DateTime.Now,
                Creator = userName,
                CreatorId = userId,
                Modifyer = userName,
                ModifyerId = userId,
                ModifyerTime = DateTime.Now,
            };
            _attachFileRepository.Insert(e);
            if (e.Id > 0)
            {
                _attachFileRepository.eviRef.Insert(new CaseAttachFileEvidenceEntity()
                {
                    attachId = e.Id,
                    Creator = e.Creator,
                    CreateTime = e.CreateTime,
                    CreatorId = e.CreatorId,
                    evidenceId = e.EvidenceId,
                    caseId = e.CaseId,
                    Modifyer = e.Modifyer,
                    ModifyerId = e.ModifyerId,
                    ModifyerTime = e.ModifyerTime,
                });
                return true;
            }
            return false;
        }


        /// <summary>
        /// 最新动态
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<TransfereEvidenceTrendResDto> GetTransfereEvidenceTrends(TokenData user)
        {
            TransfereEvidenceTrendResDto transfereEvidenceTrendResDto = new TransfereEvidenceTrendResDto();
            transfereEvidenceTrendResDto.list = new List<TransfereEvidenceTrendRes>();
            DateTime nowDate = DateTime.Now.Date;
            DateTime startTime = nowDate.AddDays(-2).Date;
            DateTime endTime = nowDate.AddDays(1).AddSeconds(-1);
            var list = _casePhysicalEvidenceRepository.GetDb()
                 .Queryable<CasePhysicalEvidenceEntity, CasePhysicalEvidenceTransfereEntity>((t1, t2) => new JoinQueryInfos(JoinType.Left, t1.Id == t2.EvidenceId))
                 .Where((t1, t2) => !t1.IsDeleted && !t2.IsDeleted && t2.CreateTime > startTime && t2.CreateTime <= endTime && t1.OrganId == user.OrganId)
                 .OrderBy((t1, t2) => t2.CreateTime, OrderByType.Desc)
                 .Select((t1, t2) => new
                 {
                     t2.DeliveryDicType,
                     t2.DeliveryDicTypeName,
                     DeliveryTimeStr = t2.DeliveryTime.Value.ToString(),
                     t2.EvidenceStatus,
                     t2.Receiver,
                     t2.Transferor,
                     t1.Name,
                     t2.EvidenceQuantity,
                     t1.Unit
                 }).ToList();
            list.ForEach(x =>
            {
                DateTime DeliveryTime = Convert.ToDateTime(x.DeliveryTimeStr);
                transfereEvidenceTrendResDto.list.Add(new TransfereEvidenceTrendRes()
                {
                    time1 = DeliveryTime.ToString("yyyy-MM-dd"),
                    time2 = DeliveryTime.ToString("HH:mm:ss"),
                    title = x.DeliveryDicTypeName,
                    label = $"{(x.EvidenceStatus == 2 ? x.Receiver : x.Transferor)}{x.DeliveryDicTypeName}物品{x.Name}{x.EvidenceQuantity}{x.Unit}"
                });
            });
            return BaseGenericResult<TransfereEvidenceTrendResDto>.Succeed(transfereEvidenceTrendResDto);
        }
    }
}
